package preprocessor.absorption.extended;

import java.util.HashSet;
import java.util.Set;

import option.KBVocabulary;

import utils.exception.ConceptException;

import kb.ABox;
import entities.Individual;
import entities.assertion.Assertion;
import entities.assertion.ConceptAssertion;
import entities.assertion.RoleAssertion;
import entities.concept.AndConcept;
import entities.concept.Concept;
import entities.concept.ExistsConcept;
import entities.concept.NotConcept;
import entities.concept.UniversalConcept;

/**
 * @deprecated
 * @author j55wu
 * 
 */
public class ABoxConvertion {

	private ABox newab;
	private Set<Assertion> newast;
	private static boolean verbose = false;

	public ABoxConvertion(ABox ab) {
		this.newab = ab;
		this.newast = new HashSet<Assertion>();
	}

	// private Individual getFreshIndi(){
	// return Individual.newBlankIndividual();
	// }

	public ABox absorb() throws ConceptException {
		ABox ab = new ABox();
		long cur = System.currentTimeMillis();
		// process concept assertions
		for (Individual i : newab.getConceptAssertions().keySet()) {
			Concept c = newab.getConceptAssertions().get(i);
			ConceptAssertion ca = new ConceptAssertion(i, this.prepareConcept(
					i, c));
			newast.add(ca);
		}
		// add all original role asts
		ab.addIndexedRoleAst(newab.getRoleAssertions());
		// add all new assertions
		ab.insertAssertions(newast);
		if (verbose) {
			System.out.println("# of all assertions under consideration: "
					+ newast.size() + "; ABox absorption time: "
					+ (System.currentTimeMillis() - cur) * 1.0 / 1000);
			System.out.println(ab.toString());
		}
		return ab;
	}

	// translate a concept, replace all (Ex R.C) by TOP
	private Concept prepareConcept(Individual a, Concept cp)
			throws ConceptException {
		if (cp instanceof AndConcept) {
			Set<Concept> cs = new HashSet<Concept>();
			for (Concept d : ((AndConcept) cp).getConceptSet()) {
				Concept ret = this.prepareConcept(a, d);
				if (!ret.equals(KBVocabulary.CONCEPT_TOP)) {
					cs.add(ret);
				}
			}
			if (cs.size() == 0) {
				return KBVocabulary.CONCEPT_TOP;
			} else if (cs.size() == 1) {
				return cs.iterator().next();
			} else {
				return new AndConcept(cs);
			}

		} else if (cp instanceof ExistsConcept) {
			this.absorbConcept(a, (ExistsConcept) cp);
			return KBVocabulary.CONCEPT_TOP;
		} else if (cp instanceof UniversalConcept) {
			UniversalConcept ucp = (UniversalConcept) cp;
			return new UniversalConcept(ucp.getRole(), this.prepareConcept(a,
					ucp.getFiller()));
		} else if (cp instanceof NotConcept) {
			if (!cp.isSimpleNot()) {
				// only NNF is considered
				throw new ConceptException(
						"Concpet not in NNF, cannot be processed for ABox absorption: "
								+ cp);
			} else {
				return cp;
			}
		} else {
			return cp;
		}
	}

	// only absorb abox concepts that are existential (no nesting)
	// a: E r.C --> a,b:r, b:C
	public void absorbConcept(Individual a, ExistsConcept ec) {
		// Set<Assertion> ret = new HashSet<Assertion>();
		Individual b = null; // this.getFreshIndi();
		RoleAssertion ra = new RoleAssertion(a, b, ec.getRole());
		this.newast.add(ra);
		if (verbose) {
			System.out.println("Assertion changes for [" + a + ":" + ec + "]");
		}
		try {
			ConceptAssertion ca = new ConceptAssertion(b, this.prepareConcept(
					b, ec.getFiller()));
			this.newast.add(ca);
			if (verbose)
				System.out.println("Assertion added:\n " + ra + "\n" + ca);
		} catch (ConceptException e) {
			e.printStackTrace();
		}
	}

	// given f, find all related features to f in the TBox
	public void findRelatedFeatures() {

	}

}
